/**
 *	@file	pgear_frm.c
 *	@brief	ポケギアメインフレーム
 *	@author	Miyuki Iwasawa
 *	@date	07.06.18
 */

#include "common.h"
#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/brightness.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/fontproc.h"
#include "system/snd_tool.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/wipe.h"
#include "system/palanm.h"
#include "system/buflen.h"
#include "system/pm_rtc.h"
#include "gflib/touchpanel.h"
#include "gflib/bg_system.h"
#include "field/field_matrix.h"
#include "field/field_place_name.h"
#include "field/zonedata.h"
#include "application/app_tool.h"
#include "application/pokegear.h"
#include "msgdata/msg.naix"

#include "pgear_sys.h"
#define __H_PGEAR_FRM_GLOBAL
#include "pgear_frm.h"
#include "pgear_act.h"
#include "pgfrm_def.h"

///プロトタイプ宣言
static void pgframe_VBankSet(void);
static void pgframe_BGLInit(PGEAR_SYS_WORK* wk);
static void pgframe_BGLRelease(PGEAR_SYS_WORK* wk);
static void pgframe_FrameResInit(PGEAR_SYS_WORK* wk);
static void pgframe_FrameResRelease(PGEAR_SYS_WORK* wk);
static void pgframe_SysActorInit(PGEAR_SYS_WORK* wk);
static void pgframe_SysActorRelease(PGEAR_SYS_WORK* wk);
static void pgframe_CursorMvInit(PGEAR_SYS_WORK* wk);
static void pgframe_CursorMvRelease(PGEAR_SYS_WORK* wk);

/**
 *	@brief	ポケギア　キーモードへの切替をチェック
 */
BOOL PGFrame_ChangeKeyModeCheck(PGEAR_SYS_WORK* wk)
{
	wk->old_key_mode = wk->key_mode;
	if(sys.trg & PAD_BUTTON_KTST_CHG){
		wk->key_mode = APP_KTST_KEY;
		return TRUE;
	}
	return FALSE;
}

/**
 *	@brief	ポケギア　タッチとキーの操作切替
 */
int PGFrame_ChangeTPkey(PGEAR_SYS_WORK* wk)
{
	if(wk->key_mode == APP_KTST_TOUCH){
		if(GF_TP_GetCont() != 0){	//
			return 0;
		}
		if(sys.cont != 0){
			if(wk->to_akey_func != NULL){
				(wk->to_akey_func)(wk->app_vwork);
			}
			wk->key_mode = APP_KTST_KEY;
			return 1;
		}
	}else{
		if(sys.cont != 0){
			return 0;
		}
		if(GF_TP_GetCont() != 0){
			if(wk->to_touch_func != NULL){
				(wk->to_touch_func)(wk->app_vwork);
			}
			wk->key_mode = APP_KTST_TOUCH;
			return 0;
		}
	}
	return 0;
}

/*
 *	@brief	ポケギア　メインフレームタッチパネル制御
 */
int PGFrame_TpControl(PGEAR_SYS_WORK* wk)
{
	int ret;
	u16 pat;
	CURSORMV_DAT* pd;

	static const RECT_HIT_TBL PGFrame_TpRect[] = {
//		{0,191,0,255}, ty,by,lx,rx
		{TP_APP_PY,TP_APP_PY+TP_APP_SY,TP_SKIN_PX,TP_SKIN_PX+TP_APP_SX},
		{TP_APP_PY,TP_APP_PY+TP_APP_SY,TP_RADIO_PX,TP_RADIO_PX+TP_APP_SX},
		{TP_APP_PY,TP_APP_PY+TP_APP_SY,TP_MAP_PX,TP_MAP_PX+TP_APP_SX},
		{TP_APP_PY,TP_APP_PY+TP_APP_SY,TP_TEL_PX,TP_TEL_PX+TP_APP_SX},
		{TP_APP_PY,TP_APP_PY+TP_APP_SY,TP_EXIT_PX,TP_EXIT_PX+TP_EXIT_SX},
		{RECT_HIT_END,0,0,0}
	};

	ret = GF_TP_RectHitTrg(PGFrame_TpRect);
	if(ret == RECT_HIT_NONE){
		return PG_NEXT_NULL;
	}
	pat = 0x0000;	//0000 0000 0001 1111	無効パレットbit(onになっている色Noのみ反応)
	if(GF_BGL_DotCheck(wk->bgl,GF_BGL_FRAME0_M,sys.tp_x,sys.tp_y,&pat) == TRUE){
		return PG_NEXT_NULL;
	}
	if(ret == wk->mode){
		return PG_NEXT_NULL;	//カレントアプリを再度選択した場合、なにもせずに帰る
	}
	if(	(ret == SBTN_RADIO && (!(wk->app_open & PGAPP_OPEN_RADIO)) ) ||
		(ret == SBTN_MAP && (!(wk->app_open & PGAPP_OPEN_MAP)) )){
		return PG_NEXT_NULL;
	}
	pd = &wk->curMan->ary[0].dat[ret];

	PGFrame_SysBtnStChange(wk,ret,TRUE);
	Snd_SePlay( (ret!=PG_NEXT_EXIT)? SE_PGEAR_APP_CHANGE : SE_PGEAR_CANCEL);  // キャンセルの時は別SE  taya

	wk->control = PGCONT_APP;
	wk->key_mode = APP_KTST_TOUCH;
	return ret;
}

/**
 *	@brief	ポケギア　システムキー入力
 */
int PGFrame_SysKeyControl(PGEAR_SYS_WORK* wk)
{
	CURSORMV_PARAM* pc;
	CURSORMV_DAT* pd;

	if(sys.trg & PAD_BUTTON_B){
		Snd_SePlay(SE_PGEAR_CANCEL);
		return PG_NEXT_EXIT;
	}

	//現在のカーソル位置のコマンドを実行
	if(sys.trg & PAD_BUTTON_A){
		pc = wk->curMan->pc;
		pd = &(pc->dat[pc->pos]);

		CursorMvMan_SetCursorDrawFlag(wk->curMan,0,FALSE);
		wk->control = PGCONT_APP;

		Snd_SePlay( (pd->id!=PG_NEXT_EXIT)? SE_PGEAR_APP_CHANGE : SE_PGEAR_CANCEL);   // キャンセルの時は別SE  taya

		if(pd->id == wk->mode){
#if 1
			if(wk->to_akey_func != NULL){	//描画状態切替
				(wk->to_akey_func)(wk->app_vwork);
			}
#endif
			return PG_NEXT_NULL;
		}else{
			PGFrame_SysBtnStChange(wk,pd->id,TRUE);
			return pd->id;
		}
	}

	if(sys.trg & PAD_KEY_LEFT){
		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		CursorMvMan_MovePos(wk->curMan,CURMV_DIR_LEFT);
		return PG_NEXT_NULL;
	}else if(sys.trg & PAD_KEY_RIGHT){
		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		CursorMvMan_MovePos(wk->curMan,CURMV_DIR_RIGHT);
		return PG_NEXT_NULL;
	}

	return PG_NEXT_NULL;
}

/*
 *	@brief	システムボタンのデフォルト表示描画
 */
void PGFrame_SysBtnDrawDef(PGEAR_SYS_WORK* wk)
{
	u8	mode;
	u8	open = wk->app_open;

	//まずはデフォルト表示
	GF_BGL_ScrWriteExpand(wk->bgl,GF_BGL_FRAME0_M,
		0,SBTN_PY,32,SBTN_SY,
		wk->pSCont->rawData,
		0,0,
		wk->pSCont->screenWidth/8,wk->pSCont->screenHeight/8);

	//アプリのオープン状態を反映
	if(!(open & PGAPP_OPEN_MAP)){
		GF_BGL_ScrWriteExpand(wk->bgl,GF_BGL_FRAME0_M,
			SBTN_MAP_PX,SBTN_PY,SBTN_APP_SX,SBTN_SY,
			wk->pSCont->rawData,
			0,SBTN_SY*2,
			wk->pSCont->screenWidth/8,wk->pSCont->screenHeight/8);
	}
	if(!(open & PGAPP_OPEN_RADIO )){
		GF_BGL_ScrWriteExpand(wk->bgl,GF_BGL_FRAME0_M,
			SBTN_RADIO_PX,SBTN_PY,SBTN_APP_SX,SBTN_SY,
			wk->pSCont->rawData,
			0,SBTN_SY*2,
			wk->pSCont->screenWidth/8,wk->pSCont->screenHeight/8);
	}
	GF_BGL_LoadScreenV_Req(wk->bgl,GF_BGL_FRAME0_M);
}

/**
 *	@brief	システムボタン表示切替
 *
 *	@param	pos	ボタンの指定
 *	@param	state	ボタンのステート指定
 */
int PGFrame_SysBtnStChange(PGEAR_SYS_WORK* wk,u8 pos,u8 state)
{
	u8	x,sx;

	PGFrame_SysBtnDrawDef(wk);

	if(pos == SBTN_EXIT){
		x = SBTN_EXIT_PX;
		sx = SBTN_EXIT_SX;
	}else{
		x = SBTN_SKIN_PX+pos*SBTN_APP_OFSX;
		sx = SBTN_APP_SX;
	}
	//アプリの選択状態を反映
	GF_BGL_ScrWriteExpand(wk->bgl,GF_BGL_FRAME0_M,
		x,SBTN_PY,SBTN_APP_SX,SBTN_SY,
		wk->pSCont->rawData,
		x,SBTN_SY*(state),
		wk->pSCont->screenWidth/8,wk->pSCont->screenHeight/8);

	GF_BGL_LoadScreenV_Req(wk->bgl,GF_BGL_FRAME0_M);
	return 0;
}

/**
 *	@brief	時間表示更新
 */
int PGFrame_UpdateTime(PGEAR_SYS_WORK* wk,BOOL flag)
{
	u8	num[4],i;
	RTCDate ndate;
	RTCTime ntime;
#if 0
	if(!flag){
		if(wk->rtc_count < 30){
			++wk->rtc_count;
			return FALSE;
		}
	}
#endif
	GF_RTC_GetDateTime(&ndate, &ntime);
	if((!flag) && (wk->otime.second == ntime.second)){
		return FALSE;
	}
	num[0] = ntime.hour / 10;
	num[1] = ntime.hour % 10;
	num[2] = ntime.minute / 10;
	num[3] = ntime.minute % 10;

	for(i = 0;i < 4;i++){
		CATS_ObjectAnimeFrameSetCap(wk->pSysAct[SYSOAM_NUM0+i],num[i]);
	}
	CATS_ObjectAnimeFrameSetCap(wk->pSysAct[SYSOAM_DAY],ndate.week);

	wk->otime = ntime;
	wk->rtc_count = 0;

	return TRUE;
}

/**
 *	@brief	ポケギア　指定座標がカントーかジョウトか判定
 */
int PGFrame_GetLocalAreaPos(u16 x,u16 z)
{
	if(x > 21){
		if(x == 25 && z == 8){	//シロガネやまはジョウト
			return PGLOCAL_JOHTO;
		}
		if(	(x == 28 && z == 6) ||
			(x == 28 && (z > 8 && z < 13))){	//セキエイ高原と26番道路
			return PGLOCAL_SEKIEI;
		}
		return PGLOCAL_KANTO;
	}
	return PGLOCAL_JOHTO;
}

/**
 *	@brief	ポケギア　フィールド上の座標がカントーかジョウトか判定
 */
int PGFrame_GetLocalArea(PGEAR_SYS_WORK* wk)
{
	return PGFrame_GetLocalAreaPos(
			wk->param->player_x/MBLOCK_GRID,wk->param->player_z/MBLOCK_GRID);
}

/**
 *	@brief	ポケギア　ローカルVramクリアと解放
 *
 *	MAIN1,2,3,SUB1,2,3は全てのアプリで初期化＆使用しているので、共通関数で処理してしまう
 */
void PGFrame_LocalVramClear(PGEAR_SYS_WORK* wk)
{
	int i;

	//ローカルパレット領域をクリア
	GF_BGL_ClearPaletteSet(GF_BGL_FRAME3_M,0x20*PGAPP_PALNUM_M,0 ,wk->heapID);
	GF_BGL_ClearPaletteSet(GF_BGL_FRAME3_S,0x20*PGAPP_PALNUM_S,0 ,wk->heapID);

	for(i = 0;i < 3;i++){
		GF_BGL_ScrClear(wk->bgl,GF_BGL_FRAME1_M+i);
		GF_BGL_ClearCharSet(GF_BGL_FRAME1_M+i,64,0,wk->heapID);
		GF_BGL_LoadScreenReq(wk->bgl,GF_BGL_FRAME1_M+i);
		GF_BGL_BGControlExit( wk->bgl,GF_BGL_FRAME1_M+i);

		GF_BGL_ScrClear(wk->bgl,GF_BGL_FRAME1_S+i);
		GF_BGL_ClearCharSet(GF_BGL_FRAME1_S+i,64,0,wk->heapID);
		GF_BGL_LoadScreenReq(wk->bgl,GF_BGL_FRAME1_S+i);
		GF_BGL_BGControlExit( wk->bgl,GF_BGL_FRAME1_S+i);
	}
}

/**
 *	@brief	ポケギア　メイン画面アプリフェード
 *
 *	@param	mode	0:フェードイン,1:フェードアウト
 *
 *	＊フェード終了後に呼ばれても問題ないように組んでおく
 *	＊呼ぶ前にpalEvy変数を0クリアしておくこと
 */
int PGFrame_MainPalFadeWait(PGEAR_SYS_WORK* wk,u8 mode)
{
	u16 col;

	if(wk->palEvy > 16){
		return TRUE;
	}

	if(mode == 0){
		SoftFadePfd(wk->palAnm,FADE_MAIN_BG,
				16*PGAPP_PALIDX_M,16*PGAPP_PALNUM_M,16-wk->palEvy,0x0000);
		SoftFadePfd(wk->palAnm,FADE_MAIN_OBJ,
				16*PGAPPOAM_PALIDX_M,16*PGAPPOAM_PALNUM_M,16-wk->palEvy,0x0000);
	}else{
		SoftFadePfd(wk->palAnm,FADE_MAIN_BG,
				16*PGAPP_PALIDX_M,16*PGAPP_PALNUM_M,wk->palEvy,0x0000);
		SoftFadePfd(wk->palAnm,FADE_MAIN_OBJ,
				16*PGAPPOAM_PALIDX_M,16*PGAPPOAM_PALNUM_M,wk->palEvy,0x0000);
	}

	if(wk->palEvy >= 16){
		wk->palEvy += 2;
		return TRUE;
	}
	wk->palEvy += 2;
	return FALSE;
}

/**
 *	@brief	ポケギア　システムカーソル　モードの位置を返す
 *	(アプリのオープン状態で、位置がずれるので)
 */
u8	PGFrame_GetSCurModePosNo(PGEAR_SYS_WORK* wk)
{
	static const u8 tbl[][4] = {
	 //exit,skin,radio,map,tel
	 {0,0xFF,0xFF,1},
	 {0,0xFF,1,2},
	 {0,1,0xFF,2},
	 {0,1,2,3},
	};
	return tbl[wk->app_open][wk->mode];
}

/**
 *	@brief	ポケギア　メインフレーム初期化
 */
int PGFrame_FrameInit(PGEAR_SYS_WORK* wk)
{
	switch(wk->sub_seq){
	case 0:
		sys_VBlankFuncChange(NULL,NULL);
		sys_HBlankIntrStop();	//HBlank割り込み禁止

		GF_Disp_GX_VisibleControlInit();
		GF_Disp_GXS_VisibleControlInit();
		GX_SetVisiblePlane(0);
		GXS_SetVisiblePlane(0);

		WIPE_SetBrightness(WIPE_DISP_MAIN,WIPE_FADE_BLACK);
		WIPE_SetBrightness(WIPE_DISP_SUB,WIPE_FADE_BLACK);
		WIPE_ResetWndMask(WIPE_DISP_MAIN);
		WIPE_ResetWndMask(WIPE_DISP_SUB);

		//タッチパネル初期化
		InitTPSystem();
		InitTPNoBuff(2);
		break;
	case 1:	//BGLシステムの初期化
		pgframe_BGLInit(wk);
		pgframe_FrameResInit(wk);
		break;
	case 2:	//システムリソースの確保と初期描画
		pgframe_SysActorInit(wk);
		pgframe_CursorMvInit(wk);
		break;
	case 3:
		sys_VBlankFuncChange(PokeGearVBlank,wk);
		wk->sub_seq = 0;
		return TRUE;
	}
	++wk->sub_seq;
	return FALSE;
}

/**
 *	@brief	ポケギア　メインフレーム開放
 */
int PGFrame_FrameRelease(PGEAR_SYS_WORK* wk)
{
	StopTP();
	sys_VBlankFuncChange(NULL,wk);

	pgframe_CursorMvRelease(wk);
	pgframe_SysActorRelease(wk);
	pgframe_FrameResRelease(wk);
	pgframe_BGLRelease(wk);
	return TRUE;
}

/**
 *	@brief	スキン別2Dリソースの読み込み
 */
void PGFrame_2DResLoad(PGEAR_SYS_WORK* wk,u8 skin)
{
	ARCHANDLE* handle;
	int	arcID;

	arcID =ARC_PGSYS_GRA;

	//アーカイブハンドル取得
	handle = ArchiveDataHandleOpen(arcID,wk->heapID);

	//キャラクタ転送
	APP_ArcFileVramLoad(wk->bgl,wk->heapID,
		handle,arcID,NARC_pgsys_gra_sysbtn001_ncgr+skin,
		GF_BGL_FRAME0_M,0,0,0);

	APP_ArcFileVramLoad(wk->bgl,wk->heapID,
		handle,arcID,NARC_pgsys_gra_sysbg001_ncgr+skin,
		GF_BGL_FRAME0_S,0,0,0);

	//パレットアニメ用ワーク
	PaletteWorkSetEx_ArcHandle(wk->palAnm,handle,
			NARC_pgsys_gra_sysbgd001_nclr+skin,wk->heapID,
			FADE_MAIN_BG,FADE_PAL_ONE_SIZE*PGSYS_PALNUM_M,16*PGSYS_PALIDX_M,16*PGSYS_PALIDX_M);
	PaletteWorkSetEx_ArcHandle(wk->palAnm,handle,
			NARC_pgsys_gra_sysbgu001_nclr+skin,wk->heapID,
			FADE_SUB_BG,FADE_PAL_ONE_SIZE*PGSYS_PALNUM_S,16*PGSYS_PALIDX_S,16*PGSYS_PALIDX_S);

	//OAMパレットアニメ用ワーク登録
	PaletteWorkSetEx_ArcHandle(wk->palAnm,handle,
			NARC_pgsys_gra_oam_sys001_nclr+skin,wk->heapID,
			FADE_MAIN_OBJ,FADE_PAL_ONE_SIZE*PGSYSOAM_PALNUM_M,
			16*PGSYSOAM_PALIDX_M,16*PGSYSOAM_PALIDX_M);
	PaletteWorkSetEx_ArcHandle(wk->palAnm,handle,
			NARC_pgsys_gra_oam_sys001_nclr+skin,wk->heapID,
			FADE_SUB_OBJ,FADE_PAL_ONE_SIZE*PGSYSOAM_PALNUM_S,
			16*PGSYSOAM_PALIDX_S,16*PGSYSOAM_PALIDX_S);

	//アプリ初期化時にバッファは既に取得済み
	ArchiveDataLoadByHandle(handle,NARC_pgsys_gra_sysbtn001_nscr+skin,wk->pSBufCont);
	NNS_G2dGetUnpackedScreenData(wk->pSBufCont,&(wk->pSCont));

	//ボタンの初期状態描画
	if(wk->mode == PGAPP_MODE_MAP_MARK){
		PGFrame_SysBtnStChange(wk,PGAPP_MODE_MAP,TRUE);
	}else{
		PGFrame_SysBtnStChange(wk,wk->mode,TRUE);
	}
	APP_ArcFileVramLoad(wk->bgl,wk->heapID,
		handle,arcID,NARC_pgsys_gra_sysbg001_nscr+skin,
		GF_BGL_FRAME0_S,1,0,0);

	//ハンドル閉じる
	ArchiveDataHandleClose( handle );

	//スクリーン転送
	GF_BGL_LoadScreenV_Req(wk->bgl,GF_BGL_FRAME0_M);
	GF_BGL_LoadScreenV_Req(wk->bgl,GF_BGL_FRAME0_S);
}

/**
 *	@brief	メインフレームVramBankセット
 */
void PGFrame_VBankSet(void)
{
	GF_BGL_DISPVRAM vramSetTable = {
		GX_VRAM_BG_128_A,				// メイン2DエンジンのBG
		GX_VRAM_BGEXTPLTT_NONE,			// メイン2DエンジンのBG拡張パレット
		GX_VRAM_SUB_BG_128_C,			// サブ2DエンジンのBG
		GX_VRAM_SUB_BGEXTPLTT_NONE,		// サブ2DエンジンのBG拡張パレット
		GX_VRAM_OBJ_64_E,				// メイン2DエンジンのOBJ
		GX_VRAM_OBJEXTPLTT_NONE,		// メイン2DエンジンのOBJ拡張パレット
		GX_VRAM_SUB_OBJ_16_I,			// サブ2DエンジンのOBJ
		GX_VRAM_SUB_OBJEXTPLTT_NONE,	// サブ2DエンジンのOBJ拡張パレット
		GX_VRAM_TEX_NONE,				// テクスチャイメージスロット
		GX_VRAM_TEXPLTT_NONE			// テクスチャパレットスロット
	};
	GF_Disp_SetBank( &vramSetTable );
}

/**
 *	@brief	メインフレーム BGLの初期化
 */
static void pgframe_BGLInit(PGEAR_SYS_WORK* wk)
{
	int i;

	//VramBankセット
	PGFrame_VBankSet();

	//BGL初期化
	wk->bgl = GF_BGL_BglIniAlloc(wk->heapID);

	//上画面をサブ,下画面をメインに切り替え
	GX_SetDispSelect(GX_DISP_SELECT_SUB_MAIN);

	//初期BGモードセット
	{
		GF_BGL_SYS_HEADER BGsys_data = {
			GX_DISPMODE_GRAPHICS,GX_BGMODE_0,GX_BGMODE_0,GX_BG0_AS_2D
		};
		GF_BGL_InitBG(&BGsys_data);
	}

	{	//BG0はフレームの占有領域
		GF_BGL_BGCNT_HEADER TextBgCntDat[] = {
		{	//MAIN BG0
			0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf800,GX_BG_CHARBASE_0x08000,GX_BG_EXTPLTT_01,
			0,0,0,FALSE},
		{	//SUB BG0
			0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf800,GX_BG_CHARBASE_0x08000,GX_BG_EXTPLTT_01,
			3,0,0,FALSE},
		};
		for(i = 0;i < 2;i++){
			GF_BGL_BGControlSet(wk->bgl,GF_BGL_FRAME0_M+i*4,
								&(TextBgCntDat[i]),GF_BGL_MODE_TEXT);
			GF_BGL_ScrClear(wk->bgl,GF_BGL_FRAME0_M+i*4);
			GF_BGL_ClearCharSet(GF_BGL_FRAME0_M+i*4,32,0,wk->heapID);
		}
	}
	//この時点ではまだ隠しておく
	GF_BGL_VisibleSet(GF_BGL_FRAME0_M,VISIBLE_OFF);
	GF_BGL_VisibleSet(GF_BGL_FRAME0_S,VISIBLE_OFF);
}

/**
 *	@brief	BGLの開放
 */
static void pgframe_BGLRelease(PGEAR_SYS_WORK* wk)
{
	//BG0開放
	GF_BGL_BGControlExit(wk->bgl,GF_BGL_FRAME0_S);
	GF_BGL_BGControlExit(wk->bgl,GF_BGL_FRAME0_M);

	//bgl開放
	sys_FreeMemoryEz(wk->bgl);

	//上画面をメイン,下画面をサブに戻す
	GX_SetDispSelect(GX_DISP_SELECT_SUB_MAIN);
}


/**
 *	@brief	システムリソースの取得
 */
static void pgframe_FrameResInit(PGEAR_SYS_WORK* wk)
{
	ARCHANDLE* handle;
	int	arcID;
	int size;

	arcID =ARC_PGSYS_GRA;

	//アーカイブハンドル取得
	handle = ArchiveDataHandleOpen(arcID,wk->heapID);

	//パレットアニメコントローラー確保
	wk->palAnm = PaletteFadeInit(wk->heapID);
	PaletteFadeWorkAllocSet( wk->palAnm, FADE_MAIN_BG, FADE_PAL_ONE_SIZE*16,wk->heapID);
	PaletteFadeWorkAllocSet( wk->palAnm, FADE_MAIN_OBJ, FADE_PAL_ONE_SIZE*16,wk->heapID);
	PaletteFadeWorkAllocSet( wk->palAnm, FADE_SUB_BG, FADE_PAL_ONE_SIZE*16,wk->heapID);
	PaletteFadeWorkAllocSet( wk->palAnm, FADE_SUB_OBJ, FADE_PAL_ONE_SIZE*16,wk->heapID);

	//ボタン用スクリーンバッファの展開場所を確保
	size = ArchiveDataSizeGet(arcID,NARC_pgsys_gra_sysbtn001_nscr);
	wk->pSBufCont = sys_AllocMemory(wk->heapID,size);

	PGFrame_2DResLoad(wk,wk->skin_id);

	//ハンドル閉じる
	ArchiveDataHandleClose( handle );
}

/**
 *	@brief	システムリソースの開放
 */
static void pgframe_FrameResRelease(PGEAR_SYS_WORK* wk)
{
	//バッファ開放
	sys_FreeMemoryEz(wk->pSBufCont);

	// パレットフェード開放
	PaletteFadeWorkAllocFree( wk->palAnm, FADE_SUB_OBJ );
	PaletteFadeWorkAllocFree( wk->palAnm, FADE_SUB_BG );
	PaletteFadeWorkAllocFree( wk->palAnm, FADE_MAIN_OBJ );
	PaletteFadeWorkAllocFree( wk->palAnm, FADE_MAIN_BG );

	//パレットフェードシステム開放
	PaletteFadeFree( wk->palAnm );
	wk->palAnm = NULL;
}

/**
 *	@brief	システムアクターの初期化
 */
static void pgframe_SysActorInit(PGEAR_SYS_WORK* wk)
{
	int i;

	PGear_ActorSysInit(wk);
	wk->pSysOam = PGSysOam_Init(wk->heapID,SYSOAM_ACTMAX,1,wk->skin_id,
								NNS_G2D_VRAM_TYPE_MAX,PGSYSOAM_CGXOFS_ADJUST);


	//システムカーソル追加
	for(i = 0;i < 4;i++){
		wk->pSysAct[SYSOAM_CLT+i] = PGSysOam_ObjAdd(wk->pSysOam,
			SYSOAM_CURSOR_X,SYSOAM_CURSOR_Y,0,0,0,SYSOAM_CLT+i,ANM_SYS_CLT+i,PGSYSOAM_VT_MAIN);
	}
	wk->pSysAct[SYSOAM_DAY] = PGSysOam_ObjAdd(wk->pSysOam,
		SYSOAM_DAY_X,SYSOAM_DAY_Y,0,0,0,SYSOAM_DAY,ANM_SYS_DAY,PGSYSOAM_VT_SUB);
	wk->pSysAct[SYSOAM_NUM0] = PGSysOam_ObjAdd(wk->pSysOam,
		SYSOAM_NUM0_X,SYSOAM_NUM_Y,0,0,0,SYSOAM_NUM0,ANM_SYS_NUM,PGSYSOAM_VT_SUB);
	wk->pSysAct[SYSOAM_NUM1] = PGSysOam_ObjAdd(wk->pSysOam,
		SYSOAM_NUM1_X,SYSOAM_NUM_Y,0,0,0,SYSOAM_NUM1,ANM_SYS_NUM,PGSYSOAM_VT_SUB);
	wk->pSysAct[SYSOAM_NUM2] = PGSysOam_ObjAdd(wk->pSysOam,
		SYSOAM_NUM2_X,SYSOAM_NUM_Y,0,0,0,SYSOAM_NUM2,ANM_SYS_NUM,PGSYSOAM_VT_SUB);
	wk->pSysAct[SYSOAM_NUM3] = PGSysOam_ObjAdd(wk->pSysOam,
		SYSOAM_NUM3_X,SYSOAM_NUM_Y,0,0,0,SYSOAM_NUM3,ANM_SYS_NUM,PGSYSOAM_VT_SUB);
	wk->pSysAct[SYSOAM_NUMCONT] = PGSysOam_ObjAdd(wk->pSysOam,
		SYSOAM_NUMCONT_X,SYSOAM_NUM_Y,0,0,0,SYSOAM_NUMCONT,ANM_SYS_NUMCONT,PGSYSOAM_VT_SUB);
	wk->pSysAct[SYSOAM_COM] = PGSysOam_ObjAdd(wk->pSysOam,
		SYSOAM_COM_X,SYSOAM_COM_Y,0,0,0,SYSOAM_COM,ANM_SYS_COM,PGSYSOAM_VT_SUB);

	//時間あわせ
	PGFrame_UpdateTime(wk,TRUE);
	CATS_ObjectAutoAnimeSetCap(wk->pSysAct[SYSOAM_NUMCONT], TRUE);

	//電話の電波状態反映
	if(	!ZoneData_GetEnableTelCallFlag(wk->param->player_zone)){
		CATS_ObjectAnimeFrameSetCap(wk->pSysAct[SYSOAM_COM],1);
	}

	//カーソル/エフェクトは一旦非表示
	for(i = SYSOAM_CLT;i <= SYSOAM_CRB;i++){
		CATS_ObjectEnableCap(wk->pSysAct[i],FALSE);
		CATS_ObjectAutoAnimeSetCap(wk->pSysAct[i], TRUE);
	}
	for(i = SYSOAM_DAY;i < SYSOAM_ACTMAX;i++){
		CATS_ObjectEnableCap(wk->pSysAct[i],TRUE);
	}
}

/**
 *	@brief	システムアクターの解放
 */
static void pgframe_SysActorRelease(PGEAR_SYS_WORK* wk)
{
	int i;

	for(i = 0;i < SYSOAM_ACTMAX;i++){
		CATS_ObjectEnableCap(wk->pSysAct[i],FALSE);
		PGSysOam_ObjDelete(wk->pSysAct[i]);
	}
	PGSysOam_Release(wk->pSysOam);
	PGear_ActorSysRelease(wk);
}



/**
 *	@brief	カーソル制御マネージャの作成
 */
static void pgframe_CursorMvInit(PGEAR_SYS_WORK* wk)
{

	///カーソル移動コードデータ
	static const CURSORMV_DAT_UNIT pgsys_keycnt00[] = {
	 {SBTN_SKIN, 2,1,-1,-1,	TP_SKIN_PX+TP_APP_SXH,TP_APP_PY+TP_APP_SYH, -CP_APP_OFSX,CP_APP_OFSX,-CP_OFSY,CP_OFSY},
	 {SBTN_TEL,  0,2,-1,-1,	TP_TEL_PX+TP_APP_SXH,TP_APP_PY+TP_APP_SYH, -CP_APP_OFSX,CP_APP_OFSX,-CP_OFSY,CP_OFSY},
	 {SBTN_EXIT, 1,0,-1,-1,	TP_EXIT_PX+TP_EXIT_SXH,TP_EXIT_PY+TP_EXIT_SYH, -CP_EXIT_OFSX,CP_EXIT_OFSX,-CP_OFSY,CP_OFSY},
	};
	static const CURSORMV_DAT_UNIT pgsys_keycnt01[] = {
	 {SBTN_SKIN, 3,1,-1,-1,	TP_SKIN_PX+TP_APP_SXH,TP_APP_PY+TP_APP_SYH, -CP_APP_OFSX,CP_APP_OFSX,-CP_OFSY,CP_OFSY},
	 {SBTN_MAP,  0,2,-1,-1,	TP_MAP_PX+TP_APP_SXH,TP_APP_PY+TP_APP_SYH, -CP_APP_OFSX,CP_APP_OFSX,-CP_OFSY,CP_OFSY},
	 {SBTN_TEL,  1,3,-1,-1,	TP_TEL_PX+TP_APP_SXH,TP_APP_PY+TP_APP_SYH, -CP_APP_OFSX,CP_APP_OFSX,-CP_OFSY,CP_OFSY},
	 {SBTN_EXIT, 2,0,-1,-1,	TP_EXIT_PX+TP_EXIT_SXH,TP_EXIT_PY+TP_EXIT_SYH, -CP_EXIT_OFSX,CP_EXIT_OFSX,-CP_OFSY,CP_OFSY},
	};
	static const CURSORMV_DAT_UNIT pgsys_keycnt02[] = {
	 {SBTN_SKIN, 3,1,-1,-1,	TP_SKIN_PX+TP_APP_SXH,TP_APP_PY+TP_APP_SYH, -CP_APP_OFSX,CP_APP_OFSX,-CP_OFSY,CP_OFSY},
	 {SBTN_RADIO,0,2,-1,-1,	TP_RADIO_PX+TP_APP_SXH,TP_APP_PY+TP_APP_SYH, -CP_APP_OFSX,CP_APP_OFSX,-CP_OFSY,CP_OFSY},
	 {SBTN_TEL,  1,3,-1,-1,	TP_TEL_PX+TP_APP_SXH,TP_APP_PY+TP_APP_SYH, -CP_APP_OFSX,CP_APP_OFSX,-CP_OFSY,CP_OFSY},
	 {SBTN_EXIT, 2,0,-1,-1,	TP_EXIT_PX+TP_EXIT_SXH,TP_EXIT_PY+TP_EXIT_SYH, -CP_EXIT_OFSX,CP_EXIT_OFSX,-CP_OFSY,CP_OFSY},
	};
	static const CURSORMV_DAT_UNIT pgsys_keycnt03[] = {
	 {SBTN_SKIN, 4,1,-1,-1,	TP_SKIN_PX+TP_APP_SXH,TP_APP_PY+TP_APP_SYH, -CP_APP_OFSX,CP_APP_OFSX,-CP_OFSY,CP_OFSY},
	 {SBTN_RADIO,0,2,-1,-1,	TP_RADIO_PX+TP_APP_SXH,TP_APP_PY+TP_APP_SYH, -CP_APP_OFSX,CP_APP_OFSX,-CP_OFSY,CP_OFSY},
	 {SBTN_MAP,  1,3,-1,-1,	TP_MAP_PX+TP_APP_SXH,TP_APP_PY+TP_APP_SYH, -CP_APP_OFSX,CP_APP_OFSX,-CP_OFSY,CP_OFSY},
	 {SBTN_TEL,  2,4,-1,-1,	TP_TEL_PX+TP_APP_SXH,TP_APP_PY+TP_APP_SYH, -CP_APP_OFSX,CP_APP_OFSX,-CP_OFSY,CP_OFSY},
	 {SBTN_EXIT, 3,0,-1,-1,	TP_EXIT_PX+TP_EXIT_SXH,TP_EXIT_PY+TP_EXIT_SYH, -CP_EXIT_OFSX,CP_EXIT_OFSX,-CP_OFSY,CP_OFSY},
	};

	static const CURSORMV_DAT_UNIT* keycnt[] = {
		pgsys_keycnt00,
		pgsys_keycnt01,
		pgsys_keycnt02,
		pgsys_keycnt03,
	};
	static const u8 keycnt_num[] = {3,4,4,5};

	//マネージャワーク作成
	wk->curMan = CursorMvMan_Create(PGKM_PARAM_MAX,wk->heapID);

	//システムボタンカーソルパラメータ登録
	CursorMvMan_EntryParamUnit(wk->curMan,keycnt[wk->app_open],keycnt_num[wk->app_open],
		0,CURMV_OAM_CATS,wk->heapID,
		(void*)wk->pSysAct[SYSOAM_CLT],(void*)wk->pSysAct[SYSOAM_CLB],
		(void*)wk->pSysAct[SYSOAM_CRT],(void*)wk->pSysAct[SYSOAM_CRB]);

	//初期の呼び出しモードで初期カーソル位置を決定
	if(wk->mode == PGAPP_MODE_MAP_MARK){
		CursorMvMan_SetCurrent(wk->curMan,PGKM_SYS_PARAM,PGAPP_MODE_MAP);
	}else{
		CursorMvMan_SetCurrent(wk->curMan,PGKM_SYS_PARAM,PGFrame_GetSCurModePosNo(wk)/*wk->mode*/);
	}
}

/**
 *	@brief	カーソル制御マネージャ破棄
 */
static void pgframe_CursorMvRelease(PGEAR_SYS_WORK* wk)
{
	CursorMvMan_DeleteParam(wk->curMan,0);

	//マネージャワーク開放
	CursorMvMan_Release(wk->curMan);
}
